% Test program to generate covariance blocks
%
% DESCRIPTION
%   The total dataset, which the covariance blocks are estimated, can be:
%   (1) Samples from a gaussian distribution with covariance Sigma and zero
%   mean or (2) samples taken from a file.
%
%   For (1), the sizes of each block covariance is uniformly generated between 0.4N
%   and N. For (2), they can be random or fixed. For (1), the combination of stocks in 
%   each block covariance matrix is random. For (2), it can be random or
%   fixed.
%
% OUTPUT
%   CovBlocks is a cell array with NumOfBlocks cells. Each cell contains a
%   Covariance matrix. 
%
%   SampleSizes defines how many samples were used to estimate each Covariance
%   matrix and is a measure of reliability for that covariance block.
%
%   Sigma defines the covariance of (1) or the sampling covariance of (2)
%   Returned for the purpose of being compared with optimization result.
%
%   StockReturns defines the returns of the stocks. For (1), they are samples from the zero mean
%   and Sigma covariance gaussian distribution. For (2), they are samples taken from a
%   file.
%
%   Combinations defines which stocks are involved in each covariance block.
%
% INPUT
%   Random let choose if the generation of the length of the subblocks is
%   random (1) or deterministic (0).
%
%   NumOfBlocks is the number of subblocks in case of random generation of
%   the length of the subblocks.
%
%   NumOfStocks is the number of variables in case of random generation.
%
%   TimeSteps is the time horizon to consider the variables over in case of
%   random generation.
%

function [CovBlocks, Combinations, SampleSizes, Sigma, StockReturns] = GetCovBlocks(Random, NumOfBlocks, NumOfStocks, TimeSteps)

if (exist('NumOfStocks')),
    temp = randn(NumOfStocks,NumOfStocks)*0.5;
    Sigma = temp'*temp;
    N = NumOfStocks; % Number of stocks
    T = TimeSteps; % Time steps

    A = randn(N,T);

    % Define returns
    StockReturns = Sigma^0.5*A;
    
    % Reliability - generate matrix of numberof samples for each covariance
    % block. 40-100% of original number of samples in Cov estimate
    SampleSizes = round(reliability*T);
    reliability = rand(NumOfBlocks,1)*0.6 + 0.4;
else
    dataset = load('data2.csv');
    StockReturns = 100 * (dataset(:, 2:end)-dataset(:, 1:end-1))./dataset(:, 1:end-1);
    
    Sigma = cov(StockReturns');
    N = size(StockReturns, 1);
    T = size(StockReturns, 2);
    
    if (Random == 0),
        NumOfBlocks = 10;
    end
    
    SampleSizes = T*ones(NumOfBlocks, 1);
end

% Generate different combinations of stocks for each market randomly
if (Random == 1)
    Combinations = cell(NumOfBlocks,1);
    for i=1:NumOfBlocks,
    % Number of stocks in sub block i
    k = 2+rand(1)*(0.5*N);
    % Randomize what combination of stocks in block i and make sure that no
    % value is equal
    temp = zeros(k,1);
        for r=1:k
            temp(r,1) = round(rand(1)*(N-1))+1;
            %Check so new value is not equal to any else.
            while r >= 2 && length(find(temp(1:r-1) == temp(r,1))) ~= 0
                temp(r,1) = round(rand(1)*(N-1))+1;
            end
        end
        Combinations{i} = sort(temp); % Sort elements to help analysis
    end
else
    Combinations{1} = [1 2 3 4 5 6 7 8];
    Combinations{2} = [7 8 9 10 11 12 13 14];
    Combinations{3} = [13 14 15 16 17 18 19 20];
    Combinations{4} = [3 4 5 15 16 18 19 20];
    Combinations{5} = [1 3 5 7 16 17 19 20];
    Combinations{6} = [6 7 10 12 14 16 18 20];
    Combinations{7} = [2 4 7 10 14 15 17 19];
    Combinations{8} = [1 3 4 6 8 10 11 12]
    Combinations{9} = [4 8 10 11 14 15 18 20];
    Combinations{10} = [2 3 5 8 13 14 15 19]
end

% Generate block covariances with different sample size for each
CovBlocks = cell(NumOfBlocks,1);
for j=1:NumOfBlocks
    CovBlocks{j} = cov((StockReturns(Combinations{j},1:SampleSizes(j)))');
end